#! /usr/bin/python3
# -*- coding: UTF-8 -*-

if __name__ == "__main__":
	raise Exception("不支持从这里调用")

__version__ = "1.0"
__all__ = ["MouseChshDao"]

from com.mousechsh.common.data.MouseChshData import MouseChshData
from com.mousechsh.common.data.MouseChshDbModel import MouseChshDbModel
from com.mousechsh.common.data.MouseChshField import MouseChshDateTimeField, MouseChshForeignStringField, \
	MouseChshIntegerField, MouseChshJsonBinField, MouseChshStringField
from com.mousechsh.common.data.json.MouseChshJson import mousechsh_json_from_json
from com.mousechsh.common.log.MouseChshLog import mousechsh_logging_exception
from com.mousechsh.common.util.MouseChshDateTime import MouseChshDateTime


class MouseChshDao:

	def __init__(self):
		self.model = None
		self.listModel = None
		self.extra = {}

	def set_model(self, model):
		if model is None:
			self.model = None
			return
		if issubclass(model, MouseChshDbModel):
			self.model = model

	def set_extra_model(self, value, *, key=None):
		if value is not None:
			if issubclass(value, MouseChshDbModel):
				if key is None:
					if value.Meta and value.Meta.TableName:
						if value.Meta.TableName == self.model.Meta.TableName:
							self.extra['Parent'] = value
						else:
							self.extra[value.Meta.TableName[2:]] = value
				else:
					self.extra[key] = value

	def set_list(self, list_model):
		if list_model is None:
			self.listModel = None
			return
		if issubclass(list_model, MouseChshData):
			self.listModel = list_model

	def parse(self, data):
		if data is None:
			return None
		if not isinstance(data, dict):
			return None
		if self.model is None:
			return data
		rows = data.get('data', [])
		cols = data.get('meta', [])
		if self.listModel is None:
			list_models = []
		else:
			list_models = self.listModel()

		for row in rows:
			item = self.model()
			for colIdx in range(0, len(cols)):

				col = cols[colIdx]
				col_name = col.name
				if col_name.startswith('C_'):
					prefix = 'C'
					col_name = col_name[2:]
				elif col_name.startswith('L_'):
					prefix = 'L'
					col_name = col_name[2:]
				elif col_name.startswith('X_'):
					prefix = 'X'
					col_name = col_name[2:]
				else:
					prefix = ''
				attr_name = item.get_attr_by_column_name(col_name)
				if attr_name is None:
					attr_name = item.get_attr_by_column_name(col_name.split('_')[0])
				attr = item.get_attr_by_name(attr_name)
				ddd = row[colIdx]

				if attr is None:
					continue
				if ddd is None:
					ddd = attr.get_default()
				if ddd is None:
					continue

				if isinstance(attr, MouseChshIntegerField):
					if prefix == 'C':
						try:
							v = int(ddd)
							item.set(attr_name, v)
						except Exception as ex:
							mousechsh_logging_exception(
								ex, "列【", col_name, "】转换数据库数据到对象时遇到整型数值转换错误："
							)
							item.set(attr_name, attr.get_default())
				elif isinstance(attr, MouseChshStringField):
					if prefix == 'C':
						try:
							if attr.get_max_length() < 0:
								v = str(ddd)
							else:
								v = str(ddd)[0: attr.get_max_length()]
							item.set(attr_name, v)
						except Exception as ex:
							mousechsh_logging_exception(
								ex, "列【", col_name, "】转换数据库数据到对象时遇到字符串转换错误："
							)
							if attr.get_default():
								item.set(attr_name, attr.get_default())
				elif isinstance(attr, MouseChshJsonBinField):
					if prefix == 'X':
						if isinstance(ddd, dict):
							item.set('@' + attr_name, ddd)
						elif isinstance(ddd, list):
							item.set('@' + attr_name, ddd)
						else:
							v = mousechsh_json_from_json(ddd, {})
							item.set('@' + attr_name, v)
					elif prefix == 'C':
						item.set(attr_name, ddd)
				elif isinstance(attr, MouseChshDateTimeField):
					if prefix == 'C':
						if isinstance(ddd, int):
							item.set(attr_name, MouseChshDateTime().from_timestamp_(ddd).to_string())
						elif isinstance(ddd, str):
							item.set(attr_name, MouseChshDateTime().from_string_(ddd).to_string())
						else:
							item.set(attr_name, ddd)
				elif isinstance(attr, MouseChshForeignStringField):
					if prefix == 'L':
						if col_name.startswith(attr.get_linked_table() + '_'):
							col_name = col_name[len(attr.get_linked_table() + '_'):]
							_item = item.get('@' + attr_name)
							if _item is None:
								_model = self.extra.get(attr.get_linked_table(), None)
								if _model is not None:
									_model = _model()
									setattr(_model, col_name, ddd)
									item.set('@' + attr_name, _model)
							else:
								setattr(_item, col_name, ddd)
								item.set('@' + attr_name, _item)
					elif prefix == 'C':
						item.set(attr_name, ddd)
				else:
					item.set(attr_name, ddd)
			list_models.append(item)

		return list_models
